﻿using System.IO;
using Sproto;
using USNetFramework.Network;
using USNetFramework.PacketBuilder;

namespace NetFramework
{
    public class NetPacketBuilder : SPPacketBuilder
    {
        private SprotoStream writer;
        private SprotoStream reader;

        // 初始化
        public override void Init()
        {
            InitStream();
            InitProto();
        }

        private void InitStream()
        {
            writer = new SprotoStream();
            reader = new SprotoStream();
        }

        private void InitProto()
        {
            string protoo = File.ReadAllText("../../Assets/Protos/socket.sproto");
            RegisterSproto(0, protoo);
            RegisterSproto(1, protoo);
        }

        public override NetPacket Pack(NetMsg _msg)
        {
            SPNetMsg msg = (SPNetMsg)_msg;
            SprotoMgr sproto = GetSprotoMgr(msg.ProtoType);
            writer.Seek(0, SprotoStream.SEEK_BEGIN);
            ushort tag = msg.ProtoID;
            string protoName;


            SprotoProtocol protocol;
            if (tag > 0)                                                        // response
            {
                protocol = sproto.GetProtocol(tag);
                msg.Data.type = protocol.response;
            }
            else                                                                // request 
            {
                protocol = sproto.GetProtocol(msg.ProtoName);
                tag = protocol.tag;
                msg.Data.type = protocol.request;
            }
            sproto.Encode(msg.Data, writer);


            SPNetPacket ret = new SPNetPacket();
            ret.ProtoType = _msg.ProtoType;
            ret.ProtoID = tag;
            ret.DataBuffer = sproto.Pack(writer.Buffer, 0, writer.Position, out int size);
            return ret;
        }

        public override void Unpack(NetPacket _packet)
        {
            SPNetPacket packet = (SPNetPacket)_packet;
            SprotoMgr sproto = GetSprotoMgr(packet.ProtoType);

            reader.Seek(0, SprotoStream.SEEK_BEGIN);
            reader.Buffer = sproto.Unpack(packet.DataBuffer, 0, packet.DataSize, out int size);

            ushort tag = packet.ProtoID;
            SprotoProtocol protocol = sproto.GetProtocol(tag);

            if (EnumRequestType.Request == packet.RequestType)                  // request
            {
                if (null != protocol.request)
                    packet.Request = sproto.Decode(protocol.request, reader);
            }
            else                                                                // response
            {
                if (null != protocol.response)
                    packet.Response = sproto.Decode(protocol.response, reader);
            }
        }

        public override NetPacket GetDecodPaddingPacket()
        {
            return new SPNetPacket();
        }
    }
}
